import os
import datetime
import shutil
import time

from spass.core.error import error
from spass.core.message import message
from spass.settings import WAREHOUSE_PATH

__w_path = WAREHOUSE_PATH
__w_assignments_path = WAREHOUSE_PATH + '/assignments'
__w_templates_path = WAREHOUSE_PATH + '/templates'

__w_template_files = '/files'
__w_template_tests = '/tests'

__w_assignment_files = '/files'
__w_assignment_tests = '/tests'
__w_assignment_teams = '/teams'

__w_assignment_versions = '/versions'
__w_assignment_version_tests = '/tests'
__w_assignment_version_files = '/files'


def _template_path(id_template):
    return str(__w_templates_path + '/' + id_template)

def _template_file_path(id_template, file_name):
    return str(_template_path(id_template) + __w_template_files +
               '/' + file_name)

def _template_test_path(id_template, test_name):
    return str(_template_path(id_template) + __w_template_tests +
               '/' + test_name)

def _assignment_path(id_assignment):
    return str(__w_assignments_path + '/' + id_assignment)

def _assignment_file_path(id_assignment, file_name):
    return str(_assignment_path(id_assignment) +
               __w_assignment_files + '/' + file_name)

def _assignment_test_path(id_assignment, test_name):
    return str(_assignment_path(id_assignment) +
               __w_assignment_tests + '/' + test_name)

def _assignment_team_path(id_assignment, id_team):
    return str(_assignment_path(id_assignment) +
               __w_assignment_teams + '/' + id_team)

def _assignment_version_path(id_assignment, id_team, id_version):
    return str(_assignment_team_path(id_assignment, id_team)
               + __w_assignment_versions + '/' + id_version)

def _assignment_version_file_path(id_assignment, id_team,
                                  id_version, file_name):
    return str(_assignment_version_path(id_assignment, id_team,
                                        id_version) +
               __w_assignment_version_files + '/' + file_name)

def _assignment_version_test_path(id_assignment, id_team,
                                  id_version, test_name):
    return str(_assignment_version_path(id_assignment, id_team,
                                        id_version) +
               __w_assignment_version_tests + '/' + test_name)

def core_w_init():
    if not os.path.isdir(__w_path):
        error('warehouse.find', ['', ''])
        return False
    return True

def core_w_create():
    if not core_w_init():
        return 1
    elif (not os.path.exists(__w_assignments_path) and
          not os.path.exists(__w_templates_path)):
        os.makedirs(__w_assignments_path)
        os.makedirs(__w_templates_path)
    return 0

def core_w_is_template(id_template):
    return os.path.exists(_template_path(id_template))

def core_w_is_assignment(id_assignment):
    return os.path.exists(_assignment_path(id_assignment))

def core_w_is_assignment_team(id_assignment, id_team):
    return os.path.exists(_assignment_team_path(id_assignment,
                                                id_team))

def core_w_is_assignment_test(id_assignment, test_name):
    return os.path.exists(_assignment_test_path(id_assignment,
                                                test_name))

def core_w_is_assignment_version(id_assignment, id_team,
                                 id_version):
    return os.path.exists(_assignment_version_path(id_assignment, id_team, id_version))

def core_w_create_template(id_template, test_path):
    shutil.copytree(test_path,
                    _template_test_path(id_template, ""))
    os.makedirs(_template_file_path(id_template, ''))

def core_w_create_assignment(id_template, id_assignment):
    shutil.copytree(_template_path(id_template),
                    _assignment_path(id_assignment))
    os.makedirs(_assignment_team_path(id_assignment, ''))

def core_w_create_assignment_team(id_assignment, id_team):
    os.makedirs(_assignment_team_path(id_assignment, id_team))

def core_w_write_test_log(id_assignment, id_team, id_version,
                          test_name, content):
    log = _assignment_version_test_path(id_assignment, id_team,
                                        id_version, test_name +
                                        ".log")
    fd = open(log, 'w')
    fd.write(content)
    fd.close 

def core_w_get_last_assigment_version(id_assignment, id_team):
    versions = _assignment_version_path(id_assignment,
                                        id_team, '')
    ls = os.listdir(versions)
    ls.sort()
    ls.reverse()
    return ls[0]

def core_w_get_list_assigment_team(id_assignment):
    return os.listdir(_assignment_team_path(id_assignment, ''))

def assignment_test_path(id_assignment, id_test):
    return _assignment_test_path(id_assignment, id_test)

def core_w_del_template(id_template):
    if not core_w_is_template(id_template):
        error('template.find', [id_template, ''])
        return 1
    
    template_root = _template_path(id_template)
    shutil.rmtree(template_root, True)
    return 0

def core_w_del_assignment(id_assignment):
    if not core_w_is_assignment(id_assignment):
        error('assignment.find', [id_assignment, ''])
        return 1
    
    assignment_root = _assignment_path(id_assignment)
    shutil.rmtree(assignment_root, True)
    return 0

def core_w_del_assignment_team(id_assignment, id_team):
    if not core_w_is_assignment_team(id_assignment, id_team):
        error('ateam.find', [id_assignment, id_team])
        return 1
    
    assignment_team_root = _assignment_path(id_assignment)
    if core_w_is_assignment_team(id_assignment, id_team):
        shutil.rmtree(assignment_team_root, True)
    return 0

def core_w_new_assignment_version(id_assignment, id_team):
    if not core_w_is_assignment(id_assignment):
        error('assignment.find', [id_assignment, ''])
        return 1
    
    if not core_w_is_assignment_team(id_assignment, id_team):
        core_w_create_assignment_team(id_assignment, id_team)

    now = datetime.datetime.now()
    id_version = str(now.year) + '-' + str(now.month) + '-'\
        + str(now.day) + '-' + str(now.hour) + '-' + str(now.minute)\
        + '-' + str(now.second)
    
    if os.path.exists(_assignment_version_path(id_assignment, id_team, id_version)):
        time.sleep(1)
        return core_w_new_assignment_version(id_assignment,
                                             id_team)
    os.makedirs(_assignment_version_file_path(
            id_assignment,id_team, id_version, ''))
    os.makedirs(_assignment_version_test_path(
            id_assignment, id_team, id_version, ''))

    message('av.new', [id_assignment, id_team, id_version])
    return id_version


def core_w_del_assignment_version(id_assignment, id_team,
                                  id_version):
    if not core_w_is_assignment_version(id_assignment, id_team,
                                        id_version):
        error('av.find', [id_assignment, id_team, id_version])
        return 1
    shutil.rmtree(_assignment_version_path(id_assignment,
                                           id_team, id_version), True)
    return 0

def core_w_new_assignment_version_file(id_assignment, id_team,
                                       id_version, file_path):
    if not os.path.exists(file_path):
        error('not.find', [file_path, ''])
        return 1
    if not core_w_is_assignment_version(id_assignment, id_team,
                                        id_version):
        error('av.find', [id_assignment, id_team, id_version])
        return 1

    target = _assignment_version_file_path(
        id_assignment, id_team, id_version,
        os.path.basename(file_path))

    if os.path.exists(target):
        error('avf.exists', [id_assignment, id_version, id_team,
                             os.path.basename(file_path)])
        return 1

    shutil.copy(file_path, target)
    return 0


def core_w_list_assignment_version_files(id_assignment, id_team,
                                         id_version):
    if not core_w_is_assignment_version(id_assignment, id_team,
                                        id_version):
        error('av.find', [id_assignment, id_team, id_version])
        return 1

    target = _assignment_version_file_path(id_assignment, id_team,
                                           id_version, '')
    count = 0
    message('avf.ls', [id_assignment, id_team, id_version])

    for f in os.listdir(target):
        print "\t- " + f
        count = count + 1
    if count == 0:
        error('no.file', [])
    return 0


def core_w_list_assignment_version_tests(id_assignment, id_team,
                                         id_version):
    if not core_w_is_assignment_version(id_assignment, id_team,
                                        id_version):
        error('av.find', [id_assignment, id_team, id_version])
        return 1

    target = _assignment_version_test_path(
        id_assignment, id_team, id_version, '')
    count = 0
    message('avt.ls', [id_assignment, id_team, id_version])
    
    for f in os.listdir(target):
        print "\t- " + f
        count = count + 1
    if count == 0:
        error('no.file', [])
    return 0


def core_w_list_assignment_versions(id_assignment, id_team):
    if not core_w_is_assignment_team(id_assignment, id_team):
        error('ateam.find', [id_assignment, id_team])
        return 1

    target = _assignment_version_path(id_assignment,
                                      id_team, '')
    count = 0
    message('av.ls', [id_assignment, id_team])
    
    for f in os.listdir(target):
        print "\t- " + f
        count = count + 1
    if count == 0:
        error('no.version', [])
    return 0


def core_w_list_assignment_tests(id_assignment):
    if not core_w_is_assignment(id_assignment):
        error('assignment.find', [id_assignment, ''])
        return 1

    target = _assignment_test_path(id_assignment, '')
    count = 0
    message('atest.ls', [id_assignment, ''])
    
    for f in os.listdir(target):
        print "\t- " + f
        count = count + 1
    if count == 0:
        error('no.test', [])
    return 0


def core_w_get_assignment_version_file(
    id_assignment, id_team, id_version, file_name, where):
    target = _assignment_version_file_path(
        id_assignment, id_team, id_version, file_name)

    if not os.path.exists(target):
        error('avf.find', [id_assignment, id_team,
                           id_version, file_name])
        return 1

    shutil.copy(target, where)
    return 0


def core_w_get_assignment_version_test(
    id_assignment, id_team, id_version, file_name, where):
    target = _assignment_version_test_path(
        id_assignment, id_team, id_version, file_name)

    if not os.path.exists(target):
        error('avt.find', [id_assignment, id_team,
                           id_version, file_name])
        return 1

    shutil.copy(target, where)
    return 0


def core_w_get_assignment_version(id_assignment, id_team,
                                  id_version, where):
    target = _assignment_version_path(id_assignment, id_team,
                                      id_version)

    if not os.path.exists(target):
        error('av.find', [id_assignment, id_team, id_version])
        return 1
    if not os.path.isdir(where):
        error('must.dir', [where, ''])
        return 1

    tocopy = where + '/' + id_assignment + '.' + id_team  +\
        '.' + id_version

    if os.path.exists(tocopy):
        error('file.exists', [tocopy, ''])
        return 1

    shutil.copytree(target, tocopy)
    return 0


def core_w_get_assignment_team(id_assignment, id_team, where):
    target = _assignment_team_path(id_assignment, id_team)

    if not os.path.exists(target):
        error('ateam.find', [id_assignment, id_team])
        return 1
    if not os.path.isdir(where):
        error('must.dir', [where, ''])
        return 1

    tocopy = where + '/' + id_assignment + '.' + id_team

    if os.path.exists(tocopy):
        error('file.exists', [tocopy, ''])
        return 1

    shutil.copytree(target, tocopy)
    return 0


def core_w_get_assignment(id_assignment, where):
    target = _assignment_path(id_assignment)

    if not os.path.exists(target):
        error('assignment.find', [id_assignment, ''])
        return 1
    if not os.path.isdir(where):
        error('must.dir', [where, ''])
        return 1
    
    tocopy = where + '/' + id_assignment

    if os.path.exists(tocopy):
        error('file.exists', [tocopy, ''])
        return 1

    shutil.copytree(target, tocopy)
    return 0

